 #This file is the for the constraint related transform. 
 #Currently supported constraints include:
 #1. Primary key.
 #2. Not null
 #3. Unique
 #4. auto_increment.(This also includes the verification if the column is of numeric type)

 #This file creates the template for the constraint transform configuration file.
 def  create_constraint_config
      constraint_transform = File.new("constraint_transform_config.csv","w")
      constraint_transform.write("create_constraint,tablename,columnname,constraintname")
      constraint_transform.write("\n")
      constraint_transform.write("drop_constraint,tablename,columnname,constraintname")
      constraint_transform.close
 end	 



 #This method decides based on the first parameter of each row if the constraint is to be added or removed.
 #User needs to mention one of the following as the first attr of each row.
  	#1. drop_constraint: if the constraint has to be dropped.
  	#2. create_constraint: is the constraint has to be created.
 def transform_constraint
      new_connection = create_new_connection 
      constraint_conflict_location = check_conflicting_constraints
      if constraint_conflict_location.size != 0 
            puts ("You have a constraint conflict between line number #{constraint_conflict_location[0]} and #{constraint_conflict_location[1]}")	
      else	
            FasterCSV.foreach("constraint_transform_config.csv") do |row|
                  if row[0] != "usage"
                        for field_counter in 0..row.length
                              if row[field_counter] == 'drop_constraint'
                                  drop_the_constraint(row[field_counter+1],row[field_counter+2],row[field_counter+3],new_connection)
                              elsif row[field_counter] == 'create_constraint'
                                  add_the_constraint(row[field_counter+1],row[field_counter+2],row[field_counter+3],new_connection)	
                              end	
                        end	
                  end
            end	
      end	
 end	 





 #This method checks if there are conflicting constraint specifications in the config file.
 def check_conflicting_constraints
	row_counter = 0 
	conflict_exists = []
	FasterCSV.foreach("constraint_transform_config.csv") do |row|
		row_counter = row_counter + 1
		if row[0] == 'create_constraint' && search_constraint(row,'create_constraint',row_counter) != nil
			conflict_exists[0] = search_constraint(row,'create_constraint',row_counter)
			conflict_exists[1] = row_counter
		elsif row[0] == 'drop_constraint' && search_constraint(row,'drop_constraint',row_counter) != nil	
			conflict_exists[0] = search_constraint(row,'drop_constraint',row_counter)
			conflict_exists[1] = row_counter
		end	
	end		
	return conflict_exists
 end





 # This method scans through entire file if there is any conflicting constraint given. 
 # In the context of the application, by conflicting constraints, 'creating and dropping the same constraint on same column of same table'. 
 def search_constraint(param_row,first_attr,row_num)
	row_counter = 0 
	FasterCSV.foreach("constraint_transform_config.csv") do |row|
		row_counter = row_counter + 1
		row[0] = first_attr
		if row == param_row && row_counter != row_num	
			return row_counter
		else
			return nil	
		end		
	end	
 end	 





 #This is the actual implementation of the drop_constraint transform.
 def drop_the_constraint(table_name,column_name,constraint_name,new_connection)
        if  constraint_name == "not_null" || constraint_name == "unique" || constraint_name == "auto_increment"
              col_specs = get_the_col_spec_for_single_col(column_name,table_name,new_connection)
              new_connection.query("ALTER TABLE #{table_name} CHANGE #{column_name} #{column_name} #{col_specs}")
        elsif constraint_name == "primary_key"
              new_connection.query("ALTER TABLE #{table_name} DROP PRIMARY KEY")
        end	
 end	

 


 
 #This is the actual implementation of the create_constraint transform. 
 def add_the_constraint(table_name,column_name,constraint_name,new_connection)
        col_specs = get_the_col_spec_for_single_col(column_name,table_name,new_connection) 
        if constraint_name == "primary_key" || constraint_name == "unique"
              new_connection.query("ALTER TABLE #{table_name} ADD PRIMARY KEY (#{column_name})")
              puts ("#{constraint_name} constraint was succesfully created.")
        end	
        if constraint_name.split(' ')[0] == 'default'
              new_connection.query("ALTER TABLE #{table_name} CHANGE #{column_name} #{column_name} #{col_specs} DEFAULT \"#{constraint_name.split(' ')[2]}\"")
              puts "default value sucessfully added."
        end	
        if  constraint_name == "not_null" 
              constraint_name = "NOT NULL"
              new_connection.query("ALTER TABLE #{table_name} CHANGE #{column_name} #{column_name} #{col_specs} #{constraint_name}")
              puts "SUCCESS...NOT NULL constraint transforms have completed."
        elsif constraint_name == "auto_increment" 
              if ["VARCHAR","TEXT","MEMO","CHAR","TINYTEXT","MEDIUMTEXT"].include? col_specs.split('(')[0].upcase
                    puts "auto_increment is possible only for the numeric fields."
              else
                    new_connection.query("ALTER TABLE #{table_name} CHANGE #{column_name} #{column_name} #{col_specs} #{constraint_name}")	
                    puts "SUCCESS...Constraint transforms have completed."
              end	
        end	
 end  
	 